<!DOCTYPE html>
<meta charset="utf-8">
<style>
    .links line {
        stroke: #999;
        stroke-opacity: 0.6;
    }
    .nodes circle {
        stroke: #fff;
        stroke-width: 1.5px;
    }
    text {
        font-family: sans-serif;
        font-size: 10px;
    }
</style>
<body>
</body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
    var width = window.innerWidth;
    var height = window.innerHeight;
    //定义画布
    var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height);
    //取得20个颜色的序列
    var color = d3.scaleOrdinal(d3.schemeCategory20);
    //定义力学结构
    var simulation = d3.forceSimulation()
        .force("link", d3.forceLink().id(function(d) { return d.id; }))
        .force("charge", d3.forceManyBody())
        .force("center", d3.forceCenter(width / 2, height / 2));
    d3.json("./test.json", function(error, graph) {
        if (error) throw error;
        var link = svg.append("g")
            .attr("class", "links")
            .selectAll("line")
            .data(graph.links)
            .enter().append("line")
            .attr("stroke-width", function(d) { return Math.sqrt(d.value); });
        var node = svg.append("g")
            .attr("class", "nodes")
            .selectAll("g")
            .data(graph.nodes)
            .enter().append("g");
        node.append("circle")
            .attr("r", function (d) {
                return 10 + d.group;
            })
            .attr("fill", function(d) { return color(d.group); })
            .call(d3.drag()
                .on("start", dragstarted)
                .on("drag", dragged)
            );
        node.append("text")
            .text(function(d) {
                return d.id;
            })
            .attr('x', 6)
            .attr('y', 3);
        node.append("title").text(function(d) { return d.id; });
        simulation
            .nodes(graph.nodes)
            .on("tick", ticked);
        simulation.force("link")
            .links(graph.links);
        function ticked() {
            link
                .attr("x1", function(d) { return d.source.x; })
                .attr("y1", function(d) { return d.source.y; })
                .attr("x2", function(d) { return d.target.x; })
                .attr("y2", function(d) { return d.target.y; });
            node
                .attr("transform", function(d) {
                    return "translate(" + d.x + "," + d.y + ")";
                });
            node
                .attr("cx", function(d) { return d.x; })
                .attr("cy", function(d) { return d.y; });
        }
    });
    function dragstarted(d) {
        if (!d3.event.active) simulation.alphaTarget(0.3).restart();
        d.fx = d.x;
        d.fy = d.y;
    }
    function dragged(d) {
        d.fx = d3.event.x;
        d.fy = d3.event.y;
    }
</script>